package com.wisdudu.blank.data.repo;

import android.support.annotation.NonNull;

import com.wisdudu.blank.data.bean.CityInfo;
import com.wisdudu.blank.data.bean.PersonalInfo;
import com.wisdudu.blank.data.bean.SystemImg;
import com.wisdudu.blank.data.bean.UserInfo;
import com.wisdudu.blank.data.bean.VersionInfo;
import com.wisdudu.blank.data.source.local.UserLocalDataSource;
import com.wisdudu.blank.data.source.remote.UserRemoteDataSource;
import com.wisdudu.blank.data.source.remote.client.retrofit.subscribers.Abs;
import com.wisdudu.blank.data.source.remote.client.retrofit.subscribers.ProgressSubscriber;
import com.wisdudu.blank.support.util.NetUtil;

import java.util.List;

import io.realm.RealmConfiguration;
import rx.Observable;
import rx.functions.Action1;
import rx.schedulers.Schedulers;

/**
 * Created by qyf on 2016/8/16.
 */

public class UserRepo implements UserDataSource {
    private static UserRepo INSTANCE = null;

    private static UserLocalDataSource mUserLocalDataSource;

    private static UserRemoteDataSource mUserRemoteDataSource;

    private UserRepo(@NonNull UserRemoteDataSource userRemoteDataSource, @NonNull UserLocalDataSource userLocalDataSource) {
        mUserLocalDataSource = userLocalDataSource;
        mUserRemoteDataSource = userRemoteDataSource;
    }

    public static UserRepo getInstance(UserRemoteDataSource userRemoteDataSource,
                                       UserLocalDataSource userLocalDataSource) {
        if (INSTANCE == null) {
            INSTANCE = new UserRepo(userRemoteDataSource, userLocalDataSource);
        }
        return INSTANCE;
    }

    public Observable<UserInfo> login(String phoneNum, String password) {
        return mUserRemoteDataSource.login(phoneNum, password).doOnNext(new Action1<UserInfo>() {
            @Override
            public void call(UserInfo userInfo) {
                mUserLocalDataSource.setLoginState(true);
                mUserLocalDataSource.saveUserInfo(userInfo);
            }
        });
    }

    /**
     * 用户注册
     *
     * @param registSubscriber
     * @param phoneNum
     * @param password
     * @param code
     */
    public void register(ProgressSubscriber<UserInfo> registSubscriber, String phoneNum, String password, String code) {
        mUserRemoteDataSource.register(registSubscriber, phoneNum, password, code);
    }

    /**
     * 获取验证码
     *
     * @param phoneNum
     * @param type
     */
    public Observable<Object> getSmsCode(String phoneNum, int type) {
        return mUserRemoteDataSource.getSmsCode(phoneNum, type);
    }


    /**
     * 完善个人资料-昵称信息接口
     *
     * @param uid
     * @param nickName
     * @param sex
     * @param type
     */
    public Observable<Object> editUserNick(int uid, String nickName, int sex, int type) {
        return mUserRemoteDataSource.editUserNick(uid, nickName, sex, type);
    }

    /**
     * 重置密码
     *
     * @param subscriber
     * @param phone
     * @param code
     * @param password
     */
    public void resetPwd(ProgressSubscriber<Abs> subscriber, String phone, String code, String password) {
        mUserRemoteDataSource.resetPwd(subscriber, phone, code, password);
    }

    /**
     * 按用户属性键修改用户信息接口
     *
     * @param key
     * @param value
     */
    public void editUserInfo(String key, String value) {
        mUserRemoteDataSource.editUserInfo(Integer.parseInt(getUid()), key, value);
    }

    /**
     * 获取系统图片
     */
    public Observable<List<SystemImg>> getSystemImg(boolean forceRemote) {
        Observable<List<SystemImg>> remoteObservable = mUserRemoteDataSource.getSystemImg()
                .doOnNext(systemImgs -> {
                    for (SystemImg systemImg : systemImgs) {
                        systemImg.photoEntities.addAll(systemImg.getPhoto());
                    }
                    mUserLocalDataSource.updateSysPhotoList(systemImgs);
                })
                .doOnNext(SystemImgs -> DataStaleConstant.updateCacheTime(DataStaleConstant.GET_SYSTEM_IMG));
        Observable<List<SystemImg>> localObservable = mUserLocalDataSource.getSysPhotoList()
                .filter(systemImgs -> systemImgs.size() > 0);
        if (NetUtil.INSTANCE.isConnected()) {
            if (forceRemote) {
                return remoteObservable;
            } else {
                return Observable.concat(localObservable, remoteObservable).first(SystemImgs -> DataStaleConstant.isUsable(DataStaleConstant.GET_SYSTEM_IMG));
            }
        } else {
            return localObservable;
        }
//        return mUserRemoteDataSource.getSystemImg();
    }

    /**
     * 判断用户是否第一次启动
     */
    public boolean isFirstLanuncher() {
        return mUserLocalDataSource.isFirstLanuncher();
    }

    public void setFirstLanuncher(boolean isLanuncher) {
        mUserLocalDataSource.setFirstLanuncher(isLanuncher);
    }

    /**
     * 判断用户是否登陆
     */
    public boolean isLogin() {
        return mUserLocalDataSource.isLogin();
    }

    /**
     * 退出登陆，清除部分缓存
     */
    public void logout() {
        mUserLocalDataSource.logout();
    }

    /**
     * 是否开启远程同步更新
     */
    public UserInfo getUserInfo() {
//        mUserRemoteDataSource.getUserInfo(49).subscribe();
        return mUserLocalDataSource.getUserInfo();
    }


//    public UserCount getUserCountCache() {
//        return mUserLocalDataSource.getUserCount();
//    }

    public Observable<PersonalInfo> getPersonalInfo(String uid) {
        return mUserRemoteDataSource.getUserInfo(Integer.parseInt(uid)).doOnNext(new Action1<PersonalInfo>() {
            @Override
            public void call(PersonalInfo personalInfo) {
                mUserLocalDataSource.updateUserInfo(personalInfo.getInfo().getBirthday());
            }
        });
    }

    public String getPhoneNum() {
        return mUserLocalDataSource.getPhoneNum();
    }

    public String getUid() {
        return mUserLocalDataSource.getUid();
    }

//    /**
//     * 初始化Realm配置,在Splash中也应加上
//     *
//     * @param phoneNum
//     */
//    public void initRealm(String phoneNum) {
//        mUserLocalDataSource.initRealm(phoneNum);
//    }
//
//    public boolean isRealmInited() {
//        return mUserLocalDataSource.isRealmInited();
//    }


    @Override
    public void getUserList() {

    }

//    public String getUid() {
//        return mUserLocalDataSource.getUid();
//    }

    public RealmConfiguration getRealmConfig() {
        return mUserLocalDataSource.getRealmConfig();
    }








    /**
     * 修改用户昵称
     *
     * @param nickname 昵称
     */
    public Observable<Object> editNickname(String nickname) {
        return mUserRemoteDataSource.editUserInfo(Integer.parseInt(getUid()), "nickname", nickname).doOnNext(new Action1<Object>() {
            @Override
            public void call(Object o) {
                mUserLocalDataSource.editNickname(nickname);
            }
        });
    }

    /**
     * 修改用户生日
     *
     * @param birthday 生日 -年-月-日
     */
    public Observable<Object> editBirthday(String birthday) {
        return mUserRemoteDataSource.editUserInfo(Integer.parseInt(getUid()), "birthday", birthday).doOnNext(new Action1<Object>() {
            @Override
            public void call(Object o) {
                mUserLocalDataSource.editBirthday(birthday);
            }
        });
    }

    /**
     * 修改性别
     *
     * @param sex 性别 1：男 2：女
     */
    public Observable<Object> editSex(Integer sex) {
        return mUserRemoteDataSource.editUserInfo(Integer.parseInt(getUid()), "sex", String.valueOf(sex)).doOnNext(new Action1<Object>() {
            @Override
            public void call(Object o) {
                mUserLocalDataSource.editSex(sex);
            }
        });
    }


    /**
     * 修改头像
     *
     * @param avatar 头像url or path
     *               传递会自动过滤http
     */
    public Observable<String> editAvatar(String avatar) {
        return mUserRemoteDataSource.uploadFile(avatar)
                .subscribeOn(Schedulers.io())
                .observeOn(Schedulers.io())
                .flatMap(str -> mUserRemoteDataSource.editUserInfo(Integer.parseInt(getUid()), "faces", str).map(o -> str))
                .doOnNext(avatarurl -> mUserLocalDataSource.editAvatar(avatarurl));
    }

    /**
     * 编辑用户信息-声纹
     *
     * @param value
     * @return
     */
    public Observable<Object> editUserInfoVoice(String value) {
        return mUserRemoteDataSource.editUserInfo(Integer.parseInt(getUid()), "voiceprint", value).doOnNext(new Action1<Object>() {
            @Override
            public void call(Object o) {
                mUserLocalDataSource.editVoice(value);
            }
        });

    }

    /**
     * 检察更新
     *
     * @return
     */
    public Observable<VersionInfo> getVersion() {
        return mUserRemoteDataSource.getVersion();
    }

    /**
     * 修改密码
     *
     * @param password
     * @param reNewPassword
     * @return
     */
    public Observable<Object> editPass(String password, String reNewPassword) {
        return mUserRemoteDataSource.editPass(getUid(), password, reNewPassword);
    }

    public Observable<Abs> feedback(String content) {
        return mUserRemoteDataSource.feedback(getUid(), content);
    }


    public Observable<List<CityInfo>> getCity(int provinceid, int region, int type) {
        Observable<List<CityInfo>> remoteObservable = mUserRemoteDataSource.getCity(provinceid, region, type)
                .doOnNext(cityInfos -> {
                    mUserLocalDataSource.saveCityInfo(cityInfos);
                })
                .doOnNext(cityInfos -> DataStaleConstant.updateCacheTime(DataStaleConstant.GET_CITY_INFO + provinceid));
        Observable<List<CityInfo>> localObservable = mUserLocalDataSource.getCityInfo(provinceid)
                .filter(cityInfos -> cityInfos.size() > 0);
        return Observable.concat(localObservable, remoteObservable).first(cityInfos -> DataStaleConstant.isUsable(DataStaleConstant.GET_CITY_INFO + provinceid));
    }

    public Observable<UserInfo> setVillage(int villageid) {
        return mUserRemoteDataSource.setVillage(villageid);
    }




    public void closeRealm() {
//        mUserLocalDataSource.closeRealm();
    }
}
